﻿package scrn;


import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import mess.*;
import cont.*;
import core.*;


/**
 * 
 * 2010.04.01 - Убран стиль SubstanceOfficeSilver2007LookAndFeel<br />
 * 
 */


// ============================================================ Менеджер экранов
public class ScrMan implements TickEvent {

private static final long serialVersionUID = 1L;


// ================================================================== Переменные
private MainFrame scrMain; // Основное окно


//====================================================================== Экраны
private One scrOne; // Экран контакта
private Room scrRoom; // Экран комнаты
public AddOne addOne; // Окно поиска контактов
public AddRoom addRoom; // Окно поиска комнат
//private Win scrSett; // Экран настроек

// ================================================================== Переменные
private static final int MAX_WINS = 5; // Максимальное кол-во открытых окон


// Среды
@SuppressWarnings("unused")
private Tick tick; // Среда анимации часов и смайлов

// Отрисовка
private Win winNow = new WinEmpty();
private Win[] wins = new Win[MAX_WINS]; // Цепочка открытых окон
private int winP = 0; // Указатель на текущее окно


// Разное


// =============================================================== Инициализация
public ScrMan() {

	Draw.init();

	JFrame.setDefaultLookAndFeelDecorated(true);

	initMain();
	Man.picAni = new PicAni();

	tick = new Tick(this, 39, Setting.tickSpeed, "TickAni");

}


// =============================================================== Инициализация
public void initMain() {

	java.awt.EventQueue.invokeLater(new Runnable() {

		public void run() {

			Thread.currentThread().setName("EDT");

			try {
				for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
					if ("Nimbus".equals(info.getName())) {
						UIManager.setLookAndFeel(info.getClassName());
						break;
					}
				}
			} catch (Exception e) {
				Mess.m("ScrMan.initMain",
						"Стиль Nimbus не найден. Использую стандартный.");
			}


			scrMain = new MainFrame();
			scrMain.setLocationRelativeTo(null);
			scrMain.setVisible(true);
		}
	});
}


// =================================================== Отобразить окно на экране
public void showMainForm() {

	try {
		while (scrMain == null) {
			Thread.sleep(200);
		}
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	scrMain.setVisible(true);
}


// ========================================================== Новый пользователь
public void showNew() {

	try {
		java.awt.EventQueue.invokeAndWait(new Runnable() {

			public void run() {

				LoginFrame loginFrame = new LoginFrame(scrMain, true);
				loginFrame.setLocationRelativeTo(null);
				loginFrame.setVisible(true);
			}
		});
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}


// ======================================================= Отобразить новое окно
public void showFrame(JFrame frame) {

	//	this.frame = frame;
	//
	//
	//	if (SwingUtilities.isEventDispatchThread()) {
	//		run();
	//	} else {
	//		try {
	//			SwingUtilities.invokeLater(this);
	//		} catch (Exception e) {
	//			e.printStackTrace();
	//		}
	//	}

}


// ======================================================================= Выход
public void exit() {

	scrMain.dispose();
	Thread.yield();
	System.exit(Frame.NORMAL);
}


// =============================================================== Тестовый вход
public static void main(String[] args) {

	new ScrMan();

	Mess.m("Test02.main", "Завершено");
}


// ==================================================== Отрисовать основное окно
public void showMain() {

	Cont cont;
	int contType;
	int contNum;

	try {

		cont = Man.contMan.getSelCont();
		contType = Man.contMan.getSelType();
		contNum = Man.contMan.getSelNum();

		scrMain.selUpdate();

		switch (contType) {

			case Cont.ONE:
				//				Mess.m("ScrMan.showMain", "Включаю экран контакта " + contNum);
				if (scrOne == null) {
					scrOne = new One();
				}

				scrOne.setCont((ContOne) cont, contNum);
				showWin(scrOne);
				break;

			case Cont.ROOM:
				//				Mess.m("ScrMan.showMain", "Включаю экран комнаты " + contNum);
				if (scrRoom == null) {
					scrRoom = new Room();
					// scrSplash = null;
				}
				scrRoom.setCont((ContRoom) cont, contNum);
				showWin(scrRoom);
				break;

			default:
				Mess.err("ScrMan.showMain",
						"Не могу отобразить контакт: неизвестный тип=" + contType);
		}


	} catch (Exception e) {
		Mess.err("ScrMan.showMain", "Не могу отобразить экран", e);
	}


}


// ============================================================= Отобразить окно
public void showWin(Win winNow) {

	// Задаем окно
	if (++winP >= MAX_WINS) {
		winP = 0;
	}

	// Отображаем окно
	winNow.show(this.winNow); // Окно готовит себя к отображению

	wins[winP] = winNow;
	this.winNow = winNow;

	this.flushGraphics();
}


// ========================================== Получен результат поиска контактов
public void inFind(int contType, Cont[] conts) {

	switch (contType) {

		case Cont.ONE:
			if (addOne != null) {
				addOne.inFind(contType, ((ContOne[]) conts));
			}
			break;

		case Cont.ROOM:
			if (addRoom != null) {
				addRoom.inFind(contType, ((ContRoom[]) conts));
			}
			break;

	}
}


public void inRoomWho(int add, ContOne[] ones) {

	// TODO Auto-generated method stub

}


//=============================================== Обработчик событий клавиатуры
public void keyPressed(int keyCode) {

	if (winNow.keyPressed(keyCode)) {
		this.flushGraphics();
	}
}


// =============================================== Обработчик событий клавиатуры
public void keyReleased(int keyCode) {

	//	if (winNow.keyPressed(keyCode)) {
	//		this.flushGraphics();
	//	}
}


// ========================================================= Отправить сообщение
public void outText(String text) {

	// Здесь возможна предварительная обработка текста

	if (text.length() >= 1) {
		Cont cont;
		int contType;
		int contNum;
		int messNum;

		try {

			cont = Man.contMan.getSelCont();
			contType = Man.contMan.getSelType();
			contNum = Man.contMan.getSelNum();


			switch (contType) {

				case Cont.ONE:

					Clock.timeUpdate();
					MessOne mess = new MessOne(OneCol.T_OUT, Clock.timeH, Clock.timeM,
							text);

					messNum = ((ContOne) cont).addMess(mess);

					try {
						Man.ioMan.outTextOne(mess, contNum, messNum);
					} catch (Exception e) {
						Mess.err("OneText.outTextOne", "Ошибка отправки сообщения");
					}

					break;

				case Cont.ROOM:
					MessRoom messSel = ((ContRoom) cont).getSel();
					MessRoom messOut;

					if (messSel != null) {
						messOut = messSel.copyIn2Out();
					} else {
						messOut = new MessRoom();
						messOut.tarType = MessRoom.TAR_ALL;
						messOut.tarCache = "Всем: ";
					}

					messOut.text = text;

					if (messOut.text.charAt(0) == '*') { // Принудительно отправляется всем
						messOut.tarType = MessRoom.TAR_ALL;
						messOut.text = messOut.text.substring(1);
					}

					messNum = ((ContRoom) cont).addMess(messOut);

					try {
						Man.ioMan.outTextRoom(contNum, messNum, messOut);
					} catch (Exception e) {
						Mess.err("One.outTextRoom", "Ошибка отправки запроса");
					}

					break;

				default:
					Mess.m("ScrMan.sendMess", "Неизвестный тип контакта " + contType);
			}

			this.showMain();

		} catch (Exception e) {
			Mess.err("ScrMan.sendMess", "Не могу отобразить экран", e);
		}
	}
}


public void showAlert(String title, String text, int showTimeSec, boolean fModal) {

	JOptionPane.showMessageDialog(null, text, title, JOptionPane.WARNING_MESSAGE);

	if (text.indexOf("Неправильный") >= 0) {
		Setting.password = null;
		showNew();
	}

}


//============================================= Извещение о пришедшем сообщении
public String getTitStr(int contType, int contNum, Message message, int nickLen) {

	String titText = "...";

	switch (contType) {

		case Cont.ONE:
			MessOne messOne = (MessOne) message;

			titText = Man.contMan.getFrom(contNum, nickLen)
					+ ": "
					+ messOne.text.substring(0, Math.min(Win.NUM_TEXT_LETT, messOne.text
							.length()));
			break;

		case Cont.ROOM:
			MessRoom messRoom = (MessRoom) message;
			if (messRoom.fromType == MessRoom.FROM_ME) {
				messRoom.fromCache = Setting.login;
			}
			titText = messRoom.fromCache.substring(0, Math.min(nickLen,
					messRoom.fromCache.length()))
					+ ": "
					+ messRoom.text.substring(0, Math.min(Win.NUM_TEXT_LETT,
							messRoom.text.length()));
			break;

		default:
			Mess.m("ScrMan.getTitStr", "Неизвестный тип контакта: " + contType);
	}

	return titText;
}


// ============================================= Размер окна отрисовки изменился
public void setSize() {

	winNow.show(null);
}


// ============================================= Извещение о пришедшем сообщении
public void inText(int contType, int contNum, Message message) {

	scrMain.inText(contType, contNum, message);

	if (winNow.inText(contType, contNum, message)) {
		this.flushGraphics();
	}
}


// ============================================================ Перерисовка окна
private void flushGraphics() {

	scrMain.rePaint();
}


// ============================================= Получено подтверждение доставки
public void inRes(int contType, int contNum) {

	switch (contType) {

		case Cont.ONE:
			if (Man.contMan.isSel(contType, contNum) && (winNow == scrOne)) {
				winNow.show(null);
				this.flushGraphics();
			}
			break;

		case Cont.ROOM:
			if (Man.contMan.isSel(contType, contNum) && (winNow == scrRoom)) {
				winNow.show(null);
				this.flushGraphics();
			}
			break;

		default:
			Mess.m("ScrMan.inText", "Неизвестный тип контакта: " + contType);
	}
}


public void fOnline(boolean fOnline) {

	showMain();
}


public void chStat(String statusText) {

	showMain();
}


// ======================================================== Тик таймера анимации
@Override
public void tick(int whoTick) {

	try {
		boolean fFlush = false;

		fFlush |= winNow.tick();

		if (fFlush) {
			this.flushGraphics();
		}


	} catch (Exception e) {
		Mess.m("ScrMan.tick", "Ошибка при тике таймера анимации", e);
	}

}


// =================================================== Отобразить окно заданного
public void showCont(int contType, int contNum) {

	Man.contMan.selCont(contType, contNum);
	scrMain.selUpdate();
	showMain();
}


// ======================================== Отобразить окно предыдущего контакта
public void showPrevCont() {

	Man.contMan.selPrev();
	scrMain.selUpdate();
	showMain();
}


// ========================================= Отобразить окно следующего контакта
public void showNextCont() {

	Man.contMan.selNext();
	scrMain.selUpdate();
	showMain();
}


// ======================================== Отобразить окно добавления контактов
public void showFindOne() {

	if (SwingUtilities.isEventDispatchThread()) {
		addOne = new AddOne();
		addOne.setLocationRelativeTo(null);
		addOne.setVisible(true);
	} else {
		try {
			SwingUtilities.invokeLater(new Runnable() {

				public void run() {

					addOne = new AddOne();
					addOne.setLocationRelativeTo(null);
					addOne.setVisible(true);
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


// =========================================== Отобразить окно добавления комнат
public void showFindRoom() {

	if (SwingUtilities.isEventDispatchThread()) {
		addRoom = new AddRoom();
		addRoom.setLocationRelativeTo(null);
		addRoom.setVisible(true);
	} else {
		try {
			SwingUtilities.invokeLater(new Runnable() {

				public void run() {

					addRoom = new AddRoom();
					addRoom.setLocationRelativeTo(null);
					addRoom.setVisible(true);
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


// ======================================================= Отобразить новое окно
//@Override
//public void run() {
//
//	if (frame != null) {
//		frame.setLocationRelativeTo(null);
//		frame.setVisible(true);
//	}
//}


}
